package Server;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;

import javax.microedition.io.Connector;
import javax.microedition.io.SocketConnection;

// 203.162.70.143 : 6700

public class ISocket {
	public static ISocket ins = null;
	public static boolean connected = false;
	// base
	private SocketConnection sc;
	private DataOutputStream outputStream;
	private InputStream inputStream;
	private Thread sendThread;
	private Thread receiveThread;
	// send
	private Vector sendingMessage=new Vector();
	private int sendByteCount=0;
	public String Key="";
	// receive
	private Processor got = null;
	
	public ISocket(){
		ins = this;
		got = new Processor();
	}
	
	public void connect(String ip, int p){
		if(connected)
			return;
		sc=null;
		final String host = ip;
		final int port = p;
		Thread t = null;
		(t = new Thread(){
			public void run() {
				connected=true;
	            try {
	                doConnect(host, port);
	            } catch (Exception ex) {
	                try {
	                    doConnect(host, port);
	                } catch (Exception e) {
	                    System.out.println("ISocket->connect(ip, port) FAIL");
	                    disconnect();
	                }
	            }
			}
		}).start();
		if(t != null) t = null;
	}
	private void doConnect(String IP, int p) throws IOException{
		 sc = (SocketConnection) Connector.open("socket://" + IP + ":" + p);
         outputStream = sc.openDataOutputStream();
         inputStream = sc.openInputStream();
         
         sendThread = new Thread(){
        	 public void run() {
        			while (ISocket.connected) {
        	            try {
        	            	int ii=0;
        	                while (sendingMessage.size() > 0) {
        	                    long startTime = System.currentTimeMillis();
        	                    String msg = (String) sendingMessage.elementAt(0);
        	                    sendingMessage.removeElementAt(0);
        	                    byte[] buffer = msg.getBytes();
        	                    if(buffer.length>0){
        	                    // write out packet length
        	                        int packetLen = buffer.length;
        	                        // write out data
        	                        outputStream.write(buffer, 0, packetLen);
        	                        sendByteCount += (packetLen);
        	                        outputStream.flush();
        	                    }
        	                    ii++;
        	                    long delayTime = 100 - (System.currentTimeMillis() - startTime); // Only 10 message per second.
        	                    if (delayTime > 0) {
        	                        Thread.sleep(delayTime);
        	                    }
        	                }
        	                Thread.sleep(50); // take a break for 50 milliseconds
        	            } catch (Exception ex) {
        	            	System.out.println("::ThreadSendData->run()");
        	            	disconnect();
        	            }
        	        }
        	        if (ISocket.connected) {
        	        	disconnect();
        	        }
        	    }
         };
         receiveThread = new Thread(){
        	 public void run() {
        		 try {
        			 int c = 0;
        			 int byteRead=0;
                     while (ISocket.connected) {
                    	InputStream is = inputStream;
                 	 	String slen="";
                 	 	String strcmd="";
                 	 	
             	 		// read length
             			while((c = is.read()) != -1 && c!='#') slen+=(char)c;
             			if(c==-1)break;
//                 		 	System.out.println("len = " + slen);
             		 	
             		 	// read cmd
             		 	while((c = is.read()) != -1 && c!='#') strcmd+=(char)c;
             		 	short cmd = Short.parseShort(strcmd);
             		 	if(c==-1)break;
//                 		 	System.out.println("cmd = " + strcmd);
             		 	
             		 	// read KEY
             		 	byte arrKey[]=new byte[32]; byteRead=0;
             		 	while(byteRead>-1 && byteRead<32) byteRead+=is.read(arrKey, byteRead, 32-byteRead);
             		 	if(byteRead==-1)break;
//                 		System.out.println("skey = " + new String(srrKey));
             		 	
             		 	if(cmd != CMDService.CMD_KEY){
             		 		// read Data
             		     	int allData = Integer.parseInt(slen)- strcmd.length() - 34; //TODO: note here
             		     	byte[] data = new byte[allData]; byteRead = 0; is.read(); // skip #
             		     	while(byteRead>-1&&byteRead<allData) byteRead+=is.read(data, byteRead, allData-byteRead);
             		     	if(byteRead==-1)break;
//                 		    System.out.println("data = " + new String(data));
             		     	
             		     	String newKey = new String(arrKey);
             				if(newKey.length()==0){
             					System.out.println("[" + strcmd + "] Khong co KEY");
             					break;
             				}
             				if(!newKey.equals(Key)){
             					System.out.println("[" + strcmd + "] KEY khong hop le");
             					break;
             				}
             				newKey = null;
             		     	got.receiveData(cmd, data);
             		 	} else {
             		 		Key = new String(arrKey);
             		 	}
                     } // while
                     if(c==-1 || byteRead==-1)
                    	 System.out.println("KHONG NHAN DC MSG");
                 } catch (Exception ex) {
                     System.out.println("ThreadReceiveData::run() "+ ex.toString());
                 }
                 
                 // ra khoi Thread nhan
                 if (ISocket.connected)
                     disconnect();
        	}
         };
         
         sendThread.start();
         receiveThread.start();
	}
	public void disconnect() {
        try {
            connected = false;
            if (outputStream != null) {
                outputStream.close();
                outputStream = null;
            }
            if (inputStream != null) {
                inputStream.close();
                inputStream = null;
            }
            if (sc != null) {
                sc.close();
                sc = null;
            }
            sendThread = null;
            receiveThread = null;
            //removeAllMsg();
            if(sendingMessage!=null)
        		sendingMessage.removeAllElements();
            Key="";
            System.gc();
            
//			//TODO: reset data
//			destroyAll();
//			removeAllPage();
//			showLoginPage();
            
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

//	private void addMessage(String message){
//		sendingMessage.addElement(message);
//	}	 
//	private void removeAllMsg(){
//		if(sendingMessage!=null)
//		sendingMessage.removeAllElements();
//	}
	public void sendData(String data) {
		String p1=data.substring(0,data.indexOf("#")+1);
		String p2=data.substring(p1.length(),data.length());
		data = p1+Key+"#"+p2;
		data = data.length()+"#"+data;
		//addMessage(data);
		sendingMessage.addElement(data);
	}
}
